package com.scau.RBAC.service.strategy;

import com.scau.RBAC.service.ExternalAuthService;
import com.scau.RBAC.service.factory.AuthAdapterFactory;
import com.scau.RBAC.service.impl.LDAPAuthAdapter;
import com.scau.RBAC.service.impl.OAuthAuthAdapter;
import lombok.Getter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicBoolean;

/**
 * 降级策略管理器，管理外部服务的可用性和降级逻辑
 */
public class DegradationStrategy {
    private static final Logger logger = LoggerFactory.getLogger(DegradationStrategy.class);
    @Getter
    private static final DegradationStrategy instance = new DegradationStrategy();
    private final List<String> degradedServices = new ArrayList<>();
    private final AtomicInteger consecutiveFailureCount = new AtomicInteger(0);
    private final AtomicBoolean isGlobalDegraded = new AtomicBoolean(false);
    private static final int MAX_FAILURE_THRESHOLD = 3;
    private static final long RECOVERY_INTERVAL_MS = 60000; // 60秒恢复间隔

    private DegradationStrategy() {
        // 启动恢复监控线程
        startRecoveryMonitor();
    }

    /**
     * 记录服务调用失败
     * @param serviceType 服务类型
     */
    public void recordFailure(String serviceType) {
        int currentFailures = consecutiveFailureCount.incrementAndGet();
        logger.warn("服务 {} 调用失败，连续失败次数: {}", serviceType, currentFailures);

        // 检查是否达到降级阈值
        if (currentFailures >= MAX_FAILURE_THRESHOLD) {
            degradeService(serviceType);
        }

        // 检查是否需要全局降级
        if (degradedServices.size() > 2) { // 如果超过2个服务降级，触发全局降级
            setGlobalDegradation(true);
        }
    }

    /**
     * 记录服务调用成功
     */
    public void recordSuccess() {
        consecutiveFailureCount.set(0);

        // 如果之前是全局降级状态，可以尝试恢复
        if (isGlobalDegraded.get()) {
            logger.info("服务调用成功，尝试恢复全局服务");
            setGlobalDegradation(false);
        }
    }

    /**
     * 降级特定服务
     * @param serviceType 服务类型
     */
    public void degradeService(String serviceType) {
        if (!degradedServices.contains(serviceType)) {
            degradedServices.add(serviceType);
            logger.warn("服务 {} 已降级，将使用默认服务", serviceType);

            // 通知适配器工厂更新服务状态
            AuthAdapterFactory factory = AuthAdapterFactory.getInstance();
            if (factory.hasAdapter(serviceType)) {
                ExternalAuthService adapter = factory.getAdapter(serviceType);
                if (adapter instanceof LDAPAuthAdapter) {
                    ((LDAPAuthAdapter) adapter).setAvailable(false);
                } else if (adapter instanceof OAuthAuthAdapter) {
                    ((OAuthAuthAdapter) adapter).setAvailable(false);
                }
            }
        }
    }

    /**
     * 恢复特定服务
     * @param serviceType 服务类型
     */
    public void recoverService(String serviceType) {
        if (degradedServices.remove(serviceType)) {
            logger.info("服务 {} 已恢复", serviceType);

            // 通知适配器工厂更新服务状态
            AuthAdapterFactory factory = AuthAdapterFactory.getInstance();
            if (factory.hasAdapter(serviceType)) {
                ExternalAuthService adapter = factory.getAdapter(serviceType);
                if (adapter instanceof LDAPAuthAdapter) {
                    ((LDAPAuthAdapter) adapter).setAvailable(true);
                } else if (adapter instanceof OAuthAuthAdapter) {
                    ((OAuthAuthAdapter) adapter).setAvailable(true);
                }
            }
        }
    }

    /**
     * 设置全局降级状态
     * @param degraded 是否降级
     */
    public void setGlobalDegradation(boolean degraded) {
        isGlobalDegraded.set(degraded);
        String status = degraded ? "已触发全局降级" : "全局服务已恢复";
        logger.warn("全局服务状态: {}", status);

        // 如果全局降级，降级所有外部服务
        if (degraded) {
            for (String serviceType : AuthAdapterFactory.getInstance().getAvailableAdapterTypes()) {
                if (!"LOCAL".equals(serviceType)) {
                    degradeService(serviceType);
                }
            }
        }
    }

    /**
     * 检查服务是否已降级
     * @param serviceType 服务类型
     */
    public boolean isServiceDegraded(String serviceType) {
        return isGlobalDegraded.get() || degradedServices.contains(serviceType);
    }

    /**
     * 启动恢复监控线程
     */
    private void startRecoveryMonitor() {
        Thread monitorThread = new Thread(() -> {
            while (true) {
                try {
                    Thread.sleep(RECOVERY_INTERVAL_MS);

                    // 尝试恢复已降级的服务
                    List<String> servicesToRecover = new ArrayList<>(degradedServices);
                    for (String serviceType : servicesToRecover) {
                        logger.info("尝试恢复降级的服务: {}", serviceType);
                        // 这里可以添加服务健康检查逻辑
                        // 简单起见，这里直接恢复
                        recoverService(serviceType);
                    }
                } catch (InterruptedException e) {
                    logger.error("恢复监控线程被中断", e);
                    Thread.currentThread().interrupt();
                    break;
                } catch (Exception e) {
                    logger.error("恢复监控线程错误", e);
                }
            }
        });

        monitorThread.setName("service-recovery-monitor");
        monitorThread.setDaemon(true);
        monitorThread.start();

        logger.info("服务恢复监控线程已启动");
    }

    /**
     * 获取当前降级的服务列表
     */
    public List<String> getDegradedServices() {
        return new ArrayList<>(degradedServices);
    }
}